package com.xbdun.web.bmp.controller.system;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.xbdun.common.api.XbdUnStringResult;
import com.xbdun.common.enums.XbdunPkgEnum;
import com.xbdun.common.qr.LoginMacResponse;
import com.xbdun.common.util.EncryptUtil;
import com.xbdun.common.util.MacUtil;
import com.xbdun.comweb.bmp.util.UserInfoUtil;
import com.xbdun.comweb.bmp.util.WebCommonUtil;
import com.xbdun.facade.bmp.constant.DubboBmpConst;
import com.xbdun.facade.bmp.exceptions.BmpBizException;
import com.xbdun.facade.bmp.request.system.LoginCanPagesRequest;
import com.xbdun.facade.bmp.request.system.QueryOrgUsersRequest;
import com.xbdun.facade.bmp.request.system.SysUserRequest;
import com.xbdun.facade.bmp.response.system.CanPagesReponse;
import com.xbdun.facade.bmp.result.system.LoginCanPagesResult;
import com.xbdun.facade.bmp.result.system.QueryOrgUsersPagerResult;
import com.xbdun.facade.bmp.result.system.SysUserResult;
import com.xbdun.facade.bmp.service.system.OrgUserFacade;
import com.xbdun.facade.bmp.service.system.SysUserFacade;
import com.xbdun.facade.validatebmp.constant.DubboValidateBmpConst;
import com.xbdun.facade.validatebmp.menus.VeriCodeEnum.LoginVeriCodeEnum;
import com.xbdun.facade.validatebmp.response.WxUnionCallPcResponse;
import com.xbdun.facade.validatebmp.result.WxUnionCallPcResult;
import com.xbdun.facade.validatebmp.service.code.VeriCodeValiFacade;
import com.xbdun.facade.validatebmp.service.qr.QrCodeFacade;
import com.xbdun.web.bmp.request.ValiUserPwdRequest;
import com.xbdun.web.bmp.request.WebOrgUsersPagerRequest;
import com.xbdun.web.bmp.result.LoginChekedResult;
import com.xbdun.web.bmp.util.ErrorPageUtil;
import com.xbdun.web.bmp.util.LoginSkipUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName: LoginController
 * @Description: 登录一系列操作
 * @author zhanggt 360730440@qq.com
 * @date 2017年4月14日 上午11:42:21
 */
@Controller
@Slf4j
public class LoginController extends BaseSystemController {
	@Value("${xbdun.url.validatebmp}")
	private String validateUrl;// 二维码地址
	// 机构用户
	@Reference(registry=DubboBmpConst.REGISTRYS)
	OrgUserFacade orgUserFacade;
	// 平台用户
	@Reference(registry=DubboBmpConst.REGISTRYS)
	SysUserFacade sysUserFacade;
	// 通用校验
	@Reference(registry=DubboValidateBmpConst.REGISTRYS)
	VeriCodeValiFacade veriCodeValiFacade;
	// 扫码
	@Reference(registry=DubboValidateBmpConst.REGISTRYS)
	QrCodeFacade qrCodeFacade;
	/**
	 * 登录首页
	 * @Description 用户登录首页
	 */
	@RequestMapping(path = "login", method = { RequestMethod.POST, RequestMethod.GET })
	public ModelAndView login() {
		//退出当前Session
		UserInfoUtil.loginOut(getRequest());
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("qrUrl", validateUrl);
		model.put("effectTime", 3);// 有效二维码生成有效时间
		model.put("nonceStr", UUID.randomUUID().toString().replaceAll("-", ""));
		model.put("scanQrKey", LoginVeriCodeEnum.LOGIN_CODE.name());
		ModelAndView view = new ModelAndView(ROOT_PATH + "login", model);
		return view;
	}

	/**
	 * 登录校验
	 * 
	 * @Title: login
	 * @Description 登录校验
	 * @param request
	 *            设定文件
	 * @return void 返回类型
	 */
	@RequestMapping(path = "loginVali", method = { RequestMethod.POST, RequestMethod.GET })
	@ResponseBody
	public XbdUnStringResult loginVali(ValiUserPwdRequest request,HttpServletResponse response) {
		XbdUnStringResult result = new XbdUnStringResult();
		try {
			// 二维码登录
			if (StringUtils.isNotBlank(request.getQrCode())) {
				WxUnionCallPcResult qrInfo = qrCodeFacade.getQrInfo(request.getQrCode());
				if (qrInfo.getSuccess()) {
					qrInfo.getData().setTimestamp(System.currentTimeMillis());
					MacUtil.encryption(qrInfo.getData());
					result.setData(EncryptUtil.encrypt(JSON.toJSONString(qrInfo.getData())));
				}
			}
			/* else {
				// 用户密码登录
				ValidateCodeRequest rpcRequest = new ValidateCodeRequest();

				// 设置验证码
				rpcRequest.setVeriCode(request.getVeriCode());
				rpcRequest.setVeriKey(LoginVeriCodeEnum.LOGIN_CODE.name());

				XbdUnStringResult validateCode = veriCodeValiFacade.validateCode(rpcRequest);
				log.info("密码登录===>" + JSON.toJSONString(validateCode));
			}*/
			if(StringUtils.isNotBlank(request.getCallback())){
				WebCommonUtil.printHtml(response,request.getCallback()+"("+JSON.toJSONString(result)+")");
				return null;
			}
		} catch (Exception e) {
			result.setBizException(e);
			log.info("登录校验异常：{}", e);
		}
		return result;
	}

	/**
	 * @Title: loadding
	 * @Description 业务逻辑跳转画面
	 * @return 设定文件
	 * @return String 返回类型
	 */
	@RequestMapping(path = "loadding", method = { RequestMethod.POST, RequestMethod.GET })
	public ModelAndView loadding(@RequestParam("data") String data, HttpServletRequest currentRequest) {
		ModelAndView view = new ModelAndView();
		try {
			LoginSkipUtil.chekedLoginQr(WebCommonUtil.getIpAddr(currentRequest), data);
			// 正在的数据验证
			view.addObject("data", data);
			view.addObject("url", WebCommonUtil.getBaseUrl() + "loginCheked");// 登录检测信息
			view.setViewName(ROOT_PATH + "loadding");
		} catch (Exception e) {
			ErrorPageUtil.toErrorPage(view, e);
		}
		// 跳转页面
		return view;
	}

	// 检测用户登录后用户的所在及机构项
	@PostMapping("loginCheked")
	@ResponseBody
	public LoginChekedResult loginCheked(@RequestParam("data") String data, HttpServletRequest currentRequest) {
		LoginChekedResult result = new LoginChekedResult();
		try {
			// 校验登录信息
			WxUnionCallPcResponse parseObject = LoginSkipUtil.chekedLoginQr(WebCommonUtil.getIpAddr(currentRequest),data);
			XbdunPkgEnum enum1 = XbdunPkgEnum.getEnum(parseObject.getPkgName());
			if (null == enum1) {
				throw BmpBizException.LOGIN_QR_MAC_FAIL.newInstance("登录的来源不系统未定义");
			}
			SysUserRequest request = new SysUserRequest();
			request.setPkgName(parseObject.getPkgName());// 包名
			request.setUnionid(parseObject.getWxUnionId());// 微信UninonId
			// 用户的正式
			SysUserResult sysUserLoginOrCreate = sysUserFacade.getSysUserLogin(request);
			// 如果不存在用户信息
			if (!sysUserLoginOrCreate.getSuccess()) {
				result.setCode(sysUserLoginOrCreate.getCode());
				result.setSubCode(sysUserLoginOrCreate.getSubCode());
				result.setSubMsg(sysUserLoginOrCreate.getSubMsg());
				result.setPageName("100000");
			}else{
				//重新设置用户编号
				parseObject.setUserCode(sysUserLoginOrCreate.getData().getUserCode());
				MacUtil.encryption(parseObject);
				result.setData(EncryptUtil.encrypt(JSON.toJSONString(parseObject)));
				//判断包名用于判断用户的登录类型
				if(XbdunPkgEnum.CUSTOMER.equals(enum1)){
					//就需要登录商户系统
					result.setPageName("500");
					result.setBizException(BmpBizException.PAGE_OPENING.newInstance("跳转到商户平台"));
				}else{
					//如果存在系统用户但是却没有机构用户,说明可能企业正在处于审核当中
					if(sysUserLoginOrCreate.getData().getToOrgCnt()==0){
						result.setPageName("500");
						result.setBackUrl(WebCommonUtil.getLoginUrl());
						result.setBizException(BmpBizException.ORG_AUTING);
					}
				}
			}
		} catch (Exception e) {
			result.setBizException(e);
		}
		return result;
	}
	
	/**
	* @Title: queryOrgUsersPager
	* @Description 签名校验
	* @param request
	* @return    设定文件
	* @return QueryOrgUsersPagerResult    返回类型
	 */
	@RequestMapping(path="macOrgs",method=RequestMethod.POST)
	@ResponseBody
	public QueryOrgUsersPagerResult queryOrgUsersPager(@RequestBody WebOrgUsersPagerRequest request){
		QueryOrgUsersPagerResult result = new QueryOrgUsersPagerResult();
		try{
			// 校验登录信息
			WxUnionCallPcResponse parseObject = LoginSkipUtil.chekedLoginQr(WebCommonUtil.getIpAddr(getRequest()),request.getData());
			XbdunPkgEnum enum1 = XbdunPkgEnum.getEnum(parseObject.getPkgName());
			if (null == enum1) {
				throw BmpBizException.LOGIN_QR_MAC_FAIL.newInstance("登录的来源不系统未定义");
			}
			//如果不存在用户编号，那么就一定是在跨流程访问
			if(null ==  parseObject.getUserCode() ||parseObject.getUserCode().longValue()<=0){
				throw BmpBizException.DEF_ERROR.newInstance("对不起您跨业务流程访问失败;");
			}
			//后台管理界面
			QueryOrgUsersRequest orgUsersReq = new QueryOrgUsersRequest();
			orgUsersReq.setPakageName(enum1.getKey());
			orgUsersReq.setUserCode(parseObject.getUserCode());
			result = orgUserFacade.queryOrgUsersPager(orgUsersReq);
			result.setPageName(StringUtils.EMPTY);
		}catch(Exception e){
			result.setBizException(e);
		}
		return result;
	}
	
	//查询用户登录可选择的平台
	@RequestMapping(path="loginCanPages",method=RequestMethod.POST)
	@ResponseBody
	public LoginCanPagesResult loginCanPages(LoginCanPagesRequest request){
		LoginCanPagesResult result = new LoginCanPagesResult();
		try{
			// 校验登录信息
			WxUnionCallPcResponse parseObject = LoginSkipUtil.chekedLoginQr(WebCommonUtil.getIpAddr(getRequest()),request.getData());
			XbdunPkgEnum enum1 = XbdunPkgEnum.getEnum(parseObject.getPkgName());
			if (null == enum1) {
				throw BmpBizException.LOGIN_QR_MAC_FAIL.newInstance("登录的来源不系统未定义");
			}
			//如果不存在用户编号，那么就一定是在跨流程访问
			if(null ==  parseObject.getUserCode() ||parseObject.getUserCode().longValue()<=0){
				throw BmpBizException.DEF_ERROR.newInstance("对不起您跨业务流程访问失败;");
			}
			if(null ==  request.getOrgCode() ||request.getOrgCode().longValue()<=0){
				throw BmpBizException.DEF_ERROR.newInstance("对不起，机构编号不能为空;");
			}
			//用户编号
			request.setUserCode(parseObject.getUserCode());
			//清空释放资源
			request.setData(StringUtils.EMPTY);
			//远程查询用户可以登录的平台
			List<LoginMacResponse> reslit = orgUserFacade.loginCanPages(request);
			if(CollectionUtils.isEmpty(reslit)){
				result.setPageName("500");
				result.setBizException(BmpBizException.DB_LIST_IS_NULL.newInstance("机构还未授权给你登录平台"));
			}else{
				//需要返回给前台列表化数据
				result.setData(new ArrayList<CanPagesReponse>());
				for(LoginMacResponse pagerReq:reslit){
					//重新设置签名内容
					CanPagesReponse canPagesReponse = new CanPagesReponse();
					
					//签名标记
					String secritVal = pagerReq.getDataMac();
					//将URL与对接的URL签名进行对接
					pagerReq.setTimestamp(System.currentTimeMillis());
					pagerReq.setDataMac(StringUtils.EMPTY);//签名数据
					pagerReq.setQrIp(parseObject.getIpAddr());//登录的IP地址
					pagerReq.setUserCode(parseObject.getUserCode());//用户编号
					pagerReq.setOrgCode(request.getOrgCode());//机构编号
					pagerReq.setSecretKey(pagerReq.getSecretKey());
					pagerReq.setNonceStr(RandomStringUtils.randomAlphabetic(9));//随机码
					pagerReq.setPkgName(parseObject.getPkgName());
					pagerReq.setLoginUrl(WebCommonUtil.getLoginUrl());
					//设置签名字符串
					MacUtil.encryption(pagerReq,pagerReq.getSecretKey(),secritVal);
					//签名内容
					canPagesReponse.setDataMac(EncryptUtil.encrypt(JSON.toJSONString(pagerReq)));
					canPagesReponse.setName(pagerReq.getName());
					canPagesReponse.setPlatDescrip(pagerReq.getPlatDescrip());
					canPagesReponse.setUrl(pagerReq.getUrl());
					result.getData().add(canPagesReponse);
				}
				
				reslit.clear();
				reslit = null;
			}
		}catch(Exception e){
			result.setBizException(e);
			result.setPageName("500");
		}
		return result;
	}
	
	/*//根据包查询出不同的页面
	private void findLoginPage(LoginChekedResult result,XbdunPkgEnum enumx){
		switch (enumx) {
		case ENTERPRISE:// 跳转到企业注册页面
			result.setPageName("100000");
			break;
		case CUSTOMER:// 客户
			result.setPageName("500");
			result.setBizException(BmpBizException.PAGE_OPENING);
			break;
		case SALESMAN:// 业务员
			result.setPageName("500");
			result.setBizException(BmpBizException.PAGE_OPENING);
			break;
		case TRANSPORTER:// 运输员
			result.setPageName("500");
			result.setBizException(BmpBizException.PAGE_OPENING);
			break;
		default:
			throw BmpBizException.LOGIN_QR_MAC_FAIL.newInstance("登录的来源不系统未定义");
		}
	}*/
}
